#ifndef SERVICE_H
#define SERVICE_H

// Standard library
#include <iostream>
#include <functional>

// Boost ASIO
#include <boost/asio.hpp>

// Not a good idea to add a using declaration in a header,
// but we can live with it for this small example
using boost::asio::ip::tcp;

template <typename EmitFunction>
class session: public std::enable_shared_from_this<session<EmitFunction>> {
    public:
        session(tcp::socket&& socket, EmitFunction emit)
            : m_socket(std::move(socket))
            , m_emit(emit)
        {
            
        }

        void start()
        {
            do_read();
        }
    private:
        using shared_session = std::enable_shared_from_this<session<EmitFunction>>;

        void do_read()
        {
            auto self = shared_session::shared_from_this();
            asio::async_read_until(
                m_socket, m_data, '\n',
                [this, self](const asio::error_code& error,
                             std::size_t size) {
                    if (!error) {
                        // Reading a line from the client and
                        // passing it to whoever listens to us
                        std::istream is(&m_data);
                        std::string line;
                        std::getline(is, line);
                        m_emit(std::move(line));

                        do_read();
                    }
                }
            )
        }
};

#endif